/*
 * renderloop.h
 *
 *  Created on: 10.09.2011
 *      Author: marcell
 */

#ifndef __RENDERLOOP_H___
#define __RENDERLOOP_H___

#include <export.h>
#include <iviewport.h>
#include <gfx/camera.h>
#include <gfx/projector.h>

struct iRenderTarget;
struct iTexture2D;
class ceCamera;
struct iDevice;
class ceLightObject;
struct iProgram;
class ceProjector;
class ceRenderBucket;
struct ceRenderEnvironment;
class ceScene;
/**
 * \addtogroup opengl
 * @{
 */

/**
 * @brief Currently the only renderloop available.
 *
 * TODO: Need to pull an interface from that class.
 */
class CE_API ceRenderLoop
{
private:
	iViewport* _viewport;

	iRenderTarget*	_renderTarget;
	iRenderTarget*	_shadowOverlayer;

  iRenderTarget*  _noShadowMap;
	iRenderTarget*	_shadowMap[3];
  ceMatrix4f			_shadowMapView[3];
  ceMatrix4f			_shadowMapProjection[3];

  ceCamera				_smCam[3];
  ceProjector			_smProj[3];

	float           _shadowMapDistances[3];

	iProgram*				_combineProgram;

	bool						_performUpdate;

  bool            _shadowEnabled;

	unsigned				_numObjects;
  void RenderViewFrustum (const ceCamera& cam, const ceProjector& proj);

private:
	void Initialize ();

	void RenderFrame (bool setTxt, iTexture2D* texture);

  void RenderShadowMap (iDevice* device,
                        ceScene* scene,
                        ceCamera& camera,
                        ceProjector& projector,
                        ceLightObject* lightObj,
                        unsigned frame);

  void RenderShadowOverlayer(iDevice* device,
                             ceRenderBucket	&bucket,
                             ceRenderEnvironment& environment,
                             ceCamera& camera,
                             ceProjector& projector);
public:
  ceRenderLoop ();
  virtual ~ceRenderLoop ();

	void SetShadowMapDistances (float d0, float d1, float d2);
	void SetCombineProgram (iProgram* program);

	void PerformUpdate (bool performUpdate);
	bool IsPerformUpdate () const;

  bool Initialize(iDevice* device);

  void SetViewport (iDevice* device, iViewport* viewport);
	const iViewport* GetViewport () const;

  void SetShadowEnabled (bool shadowEnabled);
  bool IsShadowEnabled () const;

	unsigned GetNumberOfRenderedObjects () const { return _numObjects; }

  void Render (iDevice* device, ceScene* scene, ceCamera& camera, ceProjector& projector);
};

/** @} */

#endif /* ! __RENDERLOOP_H___ */
